﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.AspNetCore.Routing;
using Zhp.Auth.IService;
using Zhp.Common.WebApp;
using Zhp.IService.Sys;

namespace Zhp.Auth
{
    public class CustomAuthorizationHandler : AuthorizationHandler<AuthorizeRequirement>
    {
        ISysUserMenuService sysUserMenuSvc;
        IOnlineService onlineSvc;

        public CustomAuthorizationHandler(ISysUserMenuService sysUserMenuSvc, IOnlineService onlineSvc)
        {
            this.sysUserMenuSvc = sysUserMenuSvc;
            this.onlineSvc = onlineSvc;
        }

        protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, AuthorizeRequirement requirement)
        {
            //获取HttpContext
            var httpContext = (context.Resource as AuthorizationFilterContext)?.HttpContext;

            if (httpContext == null)
            {
                context.Fail();
                return;
            }

            if (httpContext.User.Identity == null || httpContext.User.Identity.IsAuthenticated == false)
            {
                context.Fail();
                return;
            }

            // Elsa.WorkFlow不走授权逻辑
            if (httpContext.Request.Headers["workflow"].ToString() == "true")
            {
                context.Succeed(requirement);
                return;
            }

            // 标记AllowOnline特性的action不走授权逻辑
            // 注意：该代码适用于ASP.NET 6.0.
            var actionEndpoint = httpContext.GetEndpoint();
            if (actionEndpoint != null)
            {
                var actionAttributes = actionEndpoint.Metadata.GetOrderedMetadata<AllowOnlineAttribute>();
                if (actionAttributes.Any())
                {
                    context.Succeed(requirement);//只要执行这句话就表示验证通过了
                    return;
                }
            }

            object controllerName = httpContext.GetRouteValue("controller");
            object actionName = httpContext.GetRouteValue("action");

            string userId = httpContext.User.Claims.FirstOrDefault(c => c.Type.Equals(AuthClaimTypeConst.UserId))?.Value;

            if (string.IsNullOrEmpty(userId))
            {
                context.Fail();
                return;
            }
            else
            {
                //校验菜单
                bool has = await sysUserMenuSvc.HasPermission(Convert.ToInt64(userId), $"/{controllerName}/{actionName}".ToLower());
                if (has)
                {
                    context.Succeed(requirement);//只要执行这句话就表示验证通过了
                    return;
                }
                else
                {
                    context.Fail();
                    return;
                }
            }
        }
    }

    public class AuthorizeRequirement : IAuthorizationRequirement
    {

        public AuthorizeRequirement(string claimType)
        {
            ClaimType = claimType;
        }

        /// <summary>
        /// 认证授权类型
        /// </summary>
        public string ClaimType { get; set; }
    }
}
